package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.StrategyCatalog;
import cn.wolfcode.luowowo.query.StrategyCatalogQuery;
import cn.wolfcode.luowowo.repository.StrategyCatalogRepository;
import cn.wolfcode.luowowo.repository.StrategyRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyCatalogService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.util.DBHelper;
import cn.wolfcode.luowowo.vo.CatalogVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
public class StrategyCatalogServiceImpl implements IStrategyCatalogService{
    @Autowired
    private StrategyCatalogRepository strategyCatalogRepository;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private MongoTemplate template;
    @Override
    public List<StrategyCatalog> list() {
        //先获取所有的攻略分类对象
        List<StrategyCatalog> scList = strategyCatalogRepository.findAll();
        //遍历
        for (StrategyCatalog strategyCatalog : scList) {
            Destination dest = destinationService.select(strategyCatalog.getDestId());
        }
        return scList;
    }

    @Override
    public Page<StrategyCatalog> query(StrategyCatalogQuery qo) {
        //条件
        Query query = new Query();
        PageRequest pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(),
                Sort.Direction.DESC, "_id");
        return DBHelper.query(template,StrategyCatalog.class,query,pageable);
    }

    @Override
    public void saveOrUpdate(StrategyCatalog strategyCatalog) {
        //先通过传过来的对象的id去获取到数据库中完整的对象
        Destination dest = destinationService.select(strategyCatalog.getDestId());
        //再将传过来的对象的destName设置为查询到的对象的destName
        strategyCatalog.setDestName(dest.getName());
        //然后再执行保存或修改操作
        if(!StringUtils.hasLength(strategyCatalog.getId())){
            strategyCatalog.setId(null);
            strategyCatalogRepository.save(strategyCatalog);
        }else {
            //注意: MongoDB的更新是全量更新,所以操作是先查 再替换 再更新
            //但此时无需注意其他数据,因为刚好页面传过来的参数是与数据库中列的个数是一样的,
            //当后续还有其他情况时则再看,
            strategyCatalogRepository.save(strategyCatalog);
        }
    }

    @Override
    public void save(StrategyCatalog strategyCatalog) {
        strategyCatalog.setId(null);
        strategyCatalogRepository.save(strategyCatalog);
    }

    @Override
    public void update(StrategyCatalog strategyCatalog) {
        strategyCatalogRepository.save(strategyCatalog);
    }



    @Override
    public void delete(String id) {
        strategyCatalogRepository.deleteById(id);
    }

    @Override
    public StrategyCatalog get(String rid) {
        /*Optional<StrategyCatalog> optional = strategyCatalogRepository.findById(rid);
        if(optional.isPresent()){
            return optional.get();
        }
        return null;*/
        return strategyCatalogRepository.findById(rid).orElse(null);
    }

    @Override
    public List<StrategyCatalog> queryCatalogsByDestId(String destId) {
        //先通过目的地id获取到攻略分类集合
        List<StrategyCatalog> catalogs = strategyCatalogRepository.findByDestId(destId);
        //再遍历一下所有分类查询所有攻略(在真实开发中数据量会很多,这时就需要设计规则,查询部分数据)
        for (StrategyCatalog strategyCatalog : catalogs) {
            //再通过集合中每个攻略分类id查询攻略文档中的所有集合
            //再将其设置给攻略分类集合中的strategies集合
            strategyCatalog.setStrategies(strategyService.getCatalogList(strategyCatalog.getId()));
        }
        //最后返回结果即可
        return catalogs;
    }

    @Override
    public List<StrategyCatalog> catalogsList() {
        //先获取所有目的地
        List<StrategyCatalog> list = strategyCatalogRepository.findAll();
        Set<String> set = new HashSet<>();
        //再将目的地去重
        //  先遍历list集合
        for (StrategyCatalog strategyCatalog : list) {
            //再让set集合能够拿到目的地name
            set.add(strategyCatalog.getDestName());
        }
        //再清除list集合中的所有数据
        list.clear();
        //再遍历set集合
        for (String s : set) {
            //通过name获取到目的地name一样的对象集合
            List<StrategyCatalog> byDestName = strategyCatalogRepository.findByDestName(s);
            //获取第一个对象,再将其存入list集合中,即可完成去重操作
            list.add(byDestName.get(0));
        }
        //将每个目的地的旅游分类名设置到一个list集合中
        for (StrategyCatalog strategyCatalog : list) {
            List<StrategyCatalog> scList = strategyCatalogRepository.findByDestId(strategyCatalog.getDestId());
            strategyCatalog.setMapList(scList);
        }

        return list;
    }

    @Override
    public List<CatalogVO> groupList() {
        List<CatalogVO> list = new ArrayList<>();
        TypedAggregation<StrategyCatalog> agg = Aggregation.newAggregation(StrategyCatalog.class,
                Aggregation.group("destName").
                        push("name").as("names").
                        push("id").as("ids")
        );
        AggregationResults<Map> result = template.aggregate(agg,Map.class);
        List<Map> datas = result.getMappedResults();
        for (Map data : datas) {
            CatalogVO vo = new CatalogVO();
            vo.setDestName(data.get("_id").toString());
            List<Map<String, Object>> mm = new ArrayList<>();
            List<Object> names = (List<Object>) data.get("names");
            List<Object> ids = (List<Object>) data.get("ids");
            for (int i = 0;i < names.size(); i++) {
                Map<String, Object> vv = new HashMap<>();
                String name = names.get(i).toString();
                String id = ids.get(i).toString();
                vv.put("id", id);
                vv.put("name", name);
                mm.add(vv);
            }
            vo.setMapList(mm);
            list.add(vo);
        }
        System.out.println(list);
        return list;
    }
}
